package Parser;

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */



import grafo.*;
import java.io.File;
import org.w3c.dom.Document;
import org.w3c.dom.*;

import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.DocumentBuilder;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;

import java.lang.String;

public class ParserXMI {
     private String FILE_ADDRESS = ""; //endereço do arquivo XMI
     String TAG_ROOT= "UML:Namespace.ownedElement"; // Tag root do XMI
     String TAG_CLASSE = "UML:Class"; //Tag que simboliza uma TAG_ROOT no XMI
     String TAG_ASSOCI  = "UML:Association";
     String TAG_ASSOCI_END= "UML:AssociationEnd";
     
     
     /*String ATTRIBUTES = "UML:Attribute";
     String METHODS = "UML:Operation";
     String TAG_ROOTS = "UML:Classifier.feature"; //masih salah
     String ASSOCIACOES = "UML:Classifier.feature";     
     String CLASS_INHERITANCES = "UML:GeneralizableElement.generalization";
     */
     int contASSOCI=0;
     String[] vetorVertices = null;
     String [][] vetorArestas = null;

    public void parser() {
                
        int qtdDeTAG_ROOTs = 0;
        int cont = 0; 
        
        //Armazena todas as tags do documento XMI (classes, associações etc...)
        NodeList nodeXMI;
        NodeList nodeAssoci;
        String aux;
        String aux2;
        String aux3;
        
        
        try {

            DocumentBuilderFactory docBuilderFactory = DocumentBuilderFactory.newInstance();
            DocumentBuilder docBuilder = docBuilderFactory.newDocumentBuilder();
            Document doc = docBuilder.parse(new File(FILE_ADDRESS));
            // normalize text representation
            doc.getDocumentElement().normalize();
            System.out.println("==============================");
            nodeXMI = doc.getElementsByTagName(TAG_ROOT);      
                               
            //Mapeando as Classes
            for (int i =0; i <nodeXMI.item(0).getChildNodes().getLength();i++){
                //System.out.println("Nome da TAG_ROOT " + nodeXMI.item(0).getChildNodes().item(i).getNodeName());//getAttributes().getNamedItem("name"));
                aux = nodeXMI.item(0).getChildNodes().item(i).getNodeName();
                if(aux.equals(TAG_CLASSE)){
                    qtdDeTAG_ROOTs++;
                }
                vetorVertices = new String[qtdDeTAG_ROOTs];
            }
            
            for (int i =0; i <nodeXMI.item(0).getChildNodes().getLength();i++){
               // System.out.println("Nome da TAG_ROOT " + nodeXMI.item(0).getChildNodes().item(i).getNodeName());//getAttributes().getNamedItem("name"));
                aux = nodeXMI.item(0).getChildNodes().item(i).getNodeName();
             
                if(aux.equals(TAG_CLASSE)){
                    
                    vetorVertices[cont] = nodeXMI.item(0).getChildNodes().item(i).getAttributes().getNamedItem("xmi.id").getNodeValue();
                    //System.out.println("valor do vetor " + vetorVertices[cont]);
                    cont++;
                    
                }
            }  
                
            // Mapeando as associações
            
               for (int i2 =0; i2 <nodeXMI.item(0).getChildNodes().getLength();i2++){
                    //aux2 recebe o valor da TAG UML:Association
                    aux2 = nodeXMI.item(0).getChildNodes().item(i2).getNodeName();
                    if(aux2.equals(TAG_ASSOCI)){
                         contASSOCI++;
                         //System.out.println("Quantidade de Associacoes encontradas  "+contASSOCI );
                    }
               }
            //Inicializa o vertor que armazena as arestas, cada associação possui 2 participantes, por isso o valor contASSOCI  é multiplicado por 2
             vetorArestas = new String[contASSOCI*2][2]; 
             
                int indiceMatrizArestasLinha=0;
                for (int i2 =0; i2 <nodeXMI.item(0).getChildNodes().getLength();i2++){
                    //aux2 recebe o valor da TAG UML:Association
                   
                    aux2 = nodeXMI.item(0).getChildNodes().item(i2).getNodeName();
                    if(aux2.equals(TAG_ASSOCI)){
                            //System.out.println("NM ASSOCIACAO " + nodeXMI.item(0).getChildNodes().item(i2).getAttributes().getNamedItem("name").getNodeValue());
                            //nodeAssoci recebe o valor de todos os filhos da tag UML:Association,  esses filhos será a TAG UML:Association.connection 
                            //no XMI para cada associação existe apenas uma TAG  UML:Association e uma TAG  UML:Association.connection, logo  nodeAssoci só terá um filho
                            
                                                       
                            
                            nodeAssoci= nodeXMI.item(0).getChildNodes().item(i2).getChildNodes();
                            
                            //System.out.println(" classe da tag associaco"+nodeAssoci.item(1).getNodeName());
                            //System.out.println("tamanho de filhos de association conection " +nodeAssoci.item(1).getChildNodes().getLength());
                            //int indiceMatrizArestasColuna = 0;
                            
                            int indiceMatrizArestasColuna=0;
                            
                             
                            for (int l = 0;l<nodeAssoci.item(1).getChildNodes().getLength();l++){
                                if(nodeAssoci.item(1).getChildNodes().item(l).getNodeName().equals(TAG_ASSOCI_END)){
                                        
                                   //System.out.println(" filhos de association conection"+nodeAssoci.item(1).getChildNodes().item(l).getNodeName());
                                   NodeList nodeAux=nodeAssoci.item(1).getChildNodes().item(l).getChildNodes();
                                   
                                   
                                   for(int m=0; m<nodeAux.getLength();m++){                                       
                                       if(nodeAux.item(1).getChildNodes().item(m).getNodeName().equals(TAG_CLASSE)){
                                       //System.out.println(" Filhos de UML:AssociationEnd "+nodeAux.item(1).getChildNodes().item(m).getNodeName());
                                       //System.out.println(" Filhos de UML:AssociationEnd Valor"+nodeAux.item(1).getChildNodes().item(m).getAttributes().getNamedItem("xmi.idref").getNodeValue());
                                       vetorArestas[indiceMatrizArestasLinha][indiceMatrizArestasColuna]= nodeAux.item(1).getChildNodes().item(m).getAttributes().getNamedItem("xmi.idref").getNodeValue();
                                       //System.out.println("indiceMatrizArestasLinha"+indiceMatrizArestasLinha+"indiceMatrizArestasColuna"+indiceMatrizArestasColuna);
                                       indiceMatrizArestasColuna++;
                                                                              
                                       }
                                       
                                     } 
                                     if (indiceMatrizArestasColuna==2){
                                       indiceMatrizArestasLinha++;
                                       //System.out.println("ENTROU");
                                     }
                                   
                                                                     
                                }
                                
                          }
                           
                            
                            
                           /*for(int k=0;k<nodeAssoci.getLength();k++){
                                aux3= nodeAssoci.item(k).getChildNodes().item(k).getNodeName();
                                if(aux3.equals("UML:Class")){
                                    
                                }
                              System.out.println(" classe da tag associaco"+nodeAssoci.item(0).getChildNodes()));
                            
                            }*/
                
                        }
                    
                
            }
                
                
                
                
                
            
            
            
        } catch (SAXParseException err) {
            System.out.println("** Parsing error" + ", line "
                    + err.getLineNumber() + ", uri " + err.getSystemId());
            System.out.println(" " + err.getMessage());

        } catch (SAXException e) {
            Exception x = e.getException();
            ((x == null) ? e : x).printStackTrace();

        } catch (Throwable t) {
            t.printStackTrace();
        }
        
        
    }
    
    
    public String [] getVetorRotuloVertices(){
        return vetorVertices;
    }
    
    public String [][] getVetorArestas(){
        return vetorArestas;
    }
    
   public void imprimeVetorVertices(){
     System.out.println("IMPRIMINDO VERTICES DO XML");  
     for (int i = 0; i <vetorVertices.length; i ++){
         System.out.println(" Vertice: " +i+ " ID DA CLASSE: " + vetorVertices[i]);        
        }
   } 
    
    
    public void imprimeVetorArestas(){
        System.out.println("IMPRIMINDO A MATRIZ DE ARESTAS DO XML");
         for (int i =0;i<contASSOCI;i++){
          for(int j=0;j<vetorArestas[i].length;j++){
              System.out.print(vetorArestas[i][j] + " "); 
          }
          System.out.println("");  
      }
    }
    
    public int getQuantidadeAssociacoes(){
      return contASSOCI;
    
    }

    public String getFILE_ADDRESS() {
        return FILE_ADDRESS;
    }

    public void setFILE_ADDRESS(String FILE_ADDRESS) {
        this.FILE_ADDRESS = FILE_ADDRESS;
    }

    
}
